﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Options;
using Serilog;
using Serilog.Configuration;
using Serilog.Context;
using Serilog.Events;
using Serilog.Extensions.Hosting;
using TK.Common.Logger;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    /// SerilogExtension
    /// </summary>
    public static class SerilogExtension
    {
        /// <summary>
        /// serilog 日志封装,默认文件日志
        /// </summary>
        public static IHostBuilder AddTKSerilog<TProgram>(this IHostBuilder host, Action<LoggerSinkConfiguration> writeToAction = null) where TProgram : class
        {
            host.UseSerilog((context, provider, logconfig) =>
            {
                //可以使用LogContext动态添加结构字段
                logconfig.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Fatal);
                logconfig.MinimumLevel.Override("Microsoft", LogEventLevel.Information);
                logconfig.Enrich.FromLogContext();
                //logconfig.Enrich.WithProperty("appid", "imya", true);
                logconfig.ReadFrom.Configuration(context.Configuration);
                logconfig.ReadFrom.Services(provider);
                logconfig.WriteTo.Async(sinkConf =>
                {
                    if (writeToAction != null)
                    {
                        writeToAction(sinkConf);
                    }
                    else
                    {
                        var path = Path.Combine(Path.GetDirectoryName(typeof(TProgram).Assembly.Location), "Logs","log");
                        sinkConf.File(path
                            , outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
                            , shared: true
                            , rollingInterval: RollingInterval.Hour
                            , retainedFileTimeLimit: TimeSpan.FromDays(3));
                    }
                });
            });

            return host;
        }

        /// <summary>
        /// serilog极简日志中间件
        /// </summary>
        public static IApplicationBuilder UserTKSerilog(this IApplicationBuilder app, Action<RequestLoggingOptions> configureOptions = null)
        {
            var opts = app.ApplicationServices.GetService<IOptions<RequestLoggingOptions>>()?.Value ?? new RequestLoggingOptions();
            configureOptions?.Invoke(opts);
            opts.MessageTemplate = string.IsNullOrWhiteSpace(opts.MessageTemplate) ? RequestLoggingOptions.DefaultRequestCompletionMessageTemplate : opts.MessageTemplate;
            app.UseMiddleware<RequestLoggingMiddleware>(opts);
            return app;
        }
    }
}
